local Config = require("excel.Pet")
local PetConfig = Config.pet
local Msg =require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local PetDefine = require("pet.PetDefine")
local Grid = require("bag.Grid")
local RoleDefine = require("role.RoleDefine")
local EquipConfig = require("excel.Equip").equip
local SkillNotify  = require("skill.Notify")
local BagLogic = require("bag.BagLogic")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local EquipScore = require("excel.Equip").equipScore
local HandlerL = require("pet.HandlerL")
local ObjPet = require("core.ObjPet")
local AcvityDefine = require("activity.Define")
local RankDefine = require("rank.RankDefine")
local Log = require("common.Log")
local AtticConfig = Config.petAttic
local OtherConfig = Config.other
local ExcelMap = require("excel.Map")
local Map = require("core.Map")
local Status = require("scene.Status")
local RoleAttr = require("role.RoleAttr")
local HtmlUtil = require("common.HtmlUtil")
local ItemDefine = require("bag.ItemDefine")
local YYDaBiao = require("activity.operate.DaBiao")
local OfficialLogic = require("official.OfficialLogic")

--得到神将技能个数
function getSkillCnt(id, stage)
    local config = getCurLvPetInfo(Config[PetConfig[id].petName], PetDefine.PET_STAGE, stage)
    return config.haveSkillCount
end

--得到当前星级或等阶的配置索引
function getCurLvPetInfo(curPetConfig, type, lv, isCalc)
    for i=1, #curPetConfig do
        if curPetConfig[i].type == type and curPetConfig[i].lv == lv then
            if isCalc or (lv > 0 and not isCalc) then
                return curPetConfig[i]
            end
        end
    end
end

--附加角色属性计算
function calcRA(human, id, attrs, isUp, isCalcAll)
    if not isCalcAll or isCalcAll == 0 then
        attrs[0] = 0
    end
    local curPetConfig = Config[PetConfig[id].petName]
    local data = ObjHuman.getPet(human, id)
    local star = 0
    local stage = 0
    if data then
        star = data.star
        stage = data.stage
    else
        star = PetConfig[id].baseStar
        if id ~= 1 then
            stage = 2
        end
    end
    if isUp then
        stage = stage + 1
    end
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, stage)
    if curStageInfo then
        RoleAttr.addAttrs(attrs, curStageInfo.addRoleAttr)
        if not isUp then
            for i=1, #curStageInfo.needEquip do
                if data and data.equipStatus[i - 1] == PetDefine.PET_EQUIP_EQUIPPED then
                    RoleAttr.addAttrs(attrs, EquipConfig[curStageInfo.needEquip[i]].baseAttr)
                end
            end
        end
    end
    local curStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, star)
    if curStarInfo then
        RoleAttr.addAttrs(attrs, curStarInfo.addRoleAttr)
    end
    if data then
        for i=4, 7 do
            for j=1, attrs[0] do
                if attrs[j].key == curPetConfig[1].feedRoleAttr[i - 3][1] then
                    attrs[j].value = attrs[j].value + data.feedAttrVal[i]
                    break
                end
            end
        end
        local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
        RoleAttr.addAttrs(attrs, petLvConfig[data.lv].addAttr)
    else
        local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
        RoleAttr.addAttrs(attrs, petLvConfig[25].addAttr)
    end
    return true
end
--神将属性计算
function calcPA(human, id, attrs, isUp)
    local curPetConfig = Config[PetConfig[id].petName]
    local data = ObjHuman.getPet(human, id)
    local lv = 25
    if data then
        lv = data.lv
    end
    local curStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, data and data.star or PetConfig[id].baseStar, true)
    attrs[0] = #PetConfig[id].AttrKey
    for i=1, attrs[0] do
        attrs[i].key = PetConfig[id].AttrKey[i]
        attrs[i].value = 0
        if attrs[i].key == RoleDefine.ATK then
            attrs[i].value = attrs[i].value + lv * (curStarInfo and curStarInfo.growUpShow[1] or 0) + PetConfig[id].baseAtk
        elseif attrs[i].key == RoleDefine.DEF then
            attrs[i].value = attrs[i].value + lv * (curStarInfo and curStarInfo.growUpShow[2] or 0) + PetConfig[id].baseDef
        elseif attrs[i].key == RoleDefine.HP_MAX then
            attrs[i].value = attrs[i].value + lv * (curStarInfo and curStarInfo.growUpShow[3] or 0) + PetConfig[id].baseHp
        elseif attrs[i].key == RoleDefine.HIT then
            attrs[i].value = attrs[i].value + lv * PetConfig[id].upHit
        elseif attrs[i].key == RoleDefine.SHANBI then
            attrs[i].value = attrs[i].value + lv * PetConfig[id].upShanbi
        elseif attrs[i].key == RoleDefine.BAOJI then
            attrs[i].value = attrs[i].value + lv * PetConfig[id].upBaoji
        elseif attrs[i].key == RoleDefine.RENXING then
            attrs[i].value = attrs[i].value + lv * PetConfig[id].upRenxing
        end
    end
    if data then
        local tmpStage = data.stage
        if isUp then
            tmpStage = tmpStage + 1
        end
        local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, tmpStage)
        if not curStageInfo then
            return false
        end
        for i=1, #curStageInfo.addPetAttr do
            for j=1, attrs[0] do
                if attrs[j].key == curStageInfo.addPetAttr[i][1] then
                    attrs[j].value = attrs[j].value + curStageInfo.addPetAttr[i][2]
                end
            end
        end
        if not isUp then
            for i=1, #curStageInfo.needEquip do
                if data.equipStatus[i - 1] == PetDefine.PET_EQUIP_EQUIPPED then
                    RoleAttr.addAttrs(attrs, EquipConfig[curStageInfo.needEquip[i]].baseOtherAttr)
                end
            end
        end
        for i=0, 3 do
            for j=1, attrs[0] do
                if attrs[j].key == curPetConfig[1].feedPetAttr[i + 1][1] then
                    attrs[j].value = attrs[j].value + data.feedAttrVal[i]
                end
            end
        end
    else
        local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 2)
        if not curStageInfo then
            return false
        end
        for i=1, #curStageInfo.addPetAttr do
            for j=1, attrs[0] do
                if attrs[j].key == curStageInfo.addPetAttr[i][1] then
                    attrs[j].value = attrs[j].value + curStageInfo.addPetAttr[i][2]
                end
            end
        end
    end
    return true
end
--设置神将信息
function setPetInfo(human, info, id, isOther)
    local curPetConfig = Config[PetConfig[id].petName]
    local data = ObjHuman.getPet(human, id)
    local cache = {}
    info.id = id
    if data then
        info.lv = data.lv
        info.exp = data.exp
        local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
        info.totalExp = petLvConfig[data.lv].needExp
        info.status = data.status
        info.star = data.star
        info.stage = data.stage
        info.equipStatus[0] = 4
        for i=0, 3 do
            info.equipStatus[i+1] = data.equipStatus[i]
        end
        info.feedPA[0] = #curPetConfig[1].maxAddPetAttr
        for i=0, 3 do
            info.feedPA[i + 1].key = curPetConfig[1].feedPetAttr[i + 1][1]
            info.feedPA[i + 1].value = data.feedAttrVal[i]
        end
        info.feedRA[0] = #curPetConfig[1].maxAddRoleAttr
        for i=4, 7 do
            info.feedRA[i - 3].key = curPetConfig[1].feedRoleAttr[i - 3][1]
            info.feedRA[i - 3].value = data.feedAttrVal[i]
        end
        info.equipStatus[0] = 4
        for i=0, 3 do
            info.equipStatus[i + 1] = data.equipStatus[i]
        end
        info.equips[0] = 4
        local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage)
        for i=1, 4 do
            Grid.create(cache, curStageInfo.needEquip[i], 1)
            Grid.makeItem(cache, info.equips[i], 0, human)
        end
        if not calcPA(human, id, info.nextStageAPA, true) then
            info.nextStageAPA[0] = 0
        end
        if not calcRA(human, id, info.nextStageARA, true) then
            info.nextStageARA[0] = 0
        end
        local nextStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage + 1)
        local nextStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, data.star + 1)
        if nextStageInfo then
            info.stageUpYL = nextStageInfo.needYinliang
        else
            info.stageUpYL = 0
        end
        if nextStarInfo then
            info.starUpCnt = nextStarInfo.upStarItemCnt
            info.starUpYL = nextStarInfo.needYinliang
        else
            info.starUpYL = 0
            info.starUpCnt = 0
        end
        if isOther then
          info.remainTime = 0
        else
          info.remainTime = (data.limitTime - (os.time() - data.startTime) > 0) and data.limitTime - (os.time() - data.startTime) or 0
        end
    else
        info.status = 0
        info.lv = 1
        info.exp = 0
        info.totalExp = 0
        info.star = PetConfig[id].baseStar
        info.stage = 1
        info.equipStatus[0] = 0
        info.feedPA[0] = 0
        info.feedRA[0] = 0
        info.equipStatus[0] = 0
        info.equips[0] = 0
        info.nextStageAPA[0] = 0
        info.nextStageARA[0] = 0
        info.starUpYL = 0
        info.stageUpYL = 0
        info.starUpCnt = 0
        info.remainTime = 0
    end
    info.scale = PetConfig[id].scale
    info.head = PetConfig[id].head
    Status.makeViewInfo(info.viewInfo,0, ObjPet.getBodyInfo(nil, id))
    info.name = PetConfig[id].petMingzi
    info.zi = PetConfig[id].zi
    Grid.create(cache, PetConfig[id].needItem, PetConfig[id].jihuoNeedCnt)
    Grid.makeItem(cache, info.needItem, 0, human)
    info.maxFeedPA[0] = 4
    info.maxFeedRA[0] = 4
    for i=1,4 do
        info.maxFeedPA[i].key = curPetConfig[1].maxAddPetAttr[i][1]
        info.maxFeedPA[i].value = curPetConfig[1].maxAddPetAttr[i][2]
        info.maxFeedRA[i].key = curPetConfig[1].maxAddRoleAttr[i][1]
        info.maxFeedRA[i].value = curPetConfig[1].maxAddRoleAttr[i][2]
    end
    local tempStar = data and data.star or PetConfig[id].baseStar
    local curStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, tempStar)
    if tempStar < 5 then
        local nextStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, tempStar + 1)
        info.nextStarAddRA[0] = #nextStarInfo.addRoleAttr
        for i=1, #nextStarInfo.addRoleAttr do
            info.nextStarAddRA[i].key = nextStarInfo.addRoleAttr[i][1]
            info.nextStarAddRA[i].value = nextStarInfo.addRoleAttr[i][2] - (curStarInfo and curStarInfo.addRoleAttr[i][2] or 0)
        end
        local curStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, tempStar, true)
        info.nextStarAddPA[0] = #nextStarInfo.growUpShow
        for i=1, #nextStarInfo.growUpShow do
            if i == 1 then
                info.nextStarAddPA[i].key = RoleDefine.ATK
            elseif i == 2 then
                info.nextStarAddPA[i].key = RoleDefine.DEF
            elseif i == 3 then
                info.nextStarAddPA[i].key = RoleDefine.HP_MAX
            end
            info.nextStarAddPA[i].value = (nextStarInfo.growUpShow[i] - (curStarInfo and curStarInfo.growUpShow[i] or 0)) * info.lv
        end
    else
        info.nextStarAddPA[0] = 0
        info.nextStarAddRA[0] = 0
    end
    --当前神将属性和下一星神将属性
    calcPA(human, id, info.curAttr)
    info.power = RoleAttr.calPowerProto(info.curAttr)
    RoleAttr.addAttrs2(info.nextStarAddPA, info.curAttr)
    --当前人物属性加成，下一星人物属性加成
    calcRA(human, id, info.curAddRA)
    info.curAddRAPower = RoleAttr.calPowerProto(info.curAddRA) + skillZhandouli(human)
    RoleAttr.addAttrs2(info.nextStarAddRA, info.curAddRA)
    if data then
        data.zhandouli = info.curAddRAPower
    end
    info.nextStarPAPower = RoleAttr.calPowerProto(info.nextStarAddPA) - info.power
    info.nextStarRAPower = RoleAttr.calPowerProto(info.nextStarAddRA) - info.curAddRAPower + skillZhandouli(human)
    info.nextStagePAPower = RoleAttr.calPowerProto(info.nextStageAPA) - info.power
    info.nextStageRAPower = RoleAttr.calPowerProto(info.nextStageARA) - info.curAddRAPower + skillZhandouli(human)
    info.skill[0] = #PetConfig[id].skillId
    for i = 1, #PetConfig[id].skillId do
        SkillNotify.setSkillData(human, PetConfig[id].skillId[i], info.skill[i], data and data.status ~= 0 and data.skillLv[i-1] or 0, nil, isOther)
    end
    info.skill[0] = info.skill[0] + 1
    local star1 = 1
    if data and data.star >= 1 then
        star1 = data.star
    end
    SkillNotify.setSkillData(human, PetConfig[id].starSkill[star1], info.skill[info.skill[0]], data and data.status ~= 0 and 1 or 0, nil, isOther)
    info.power = info.power + skillZhandouli(human)
end
--更新神将
function updatePet(human, petId)
    local sendMsg = Msg.gc.GC_UPDATE_PET
    setPetInfo(human, sendMsg.info, petId)
    Msg.send(sendMsg, human.fd)
    if petId == human.db.petCombatId then
        ObjPet.reset(human, petId)
    end
end
--发送神将列表
function sendPetList(human)
    local sendMsg = Msg.gc.GC_PET_LIST
    sendMsg.feedYinliang = 10000
    sendMsg.list[0] = #PetConfig
    for i=1, #PetConfig do
        setPetInfo(human, sendMsg.list[i], i)
    end
    Msg.send(sendMsg, human.fd)
    sendPetLvItem(human)
end
--升星
function starUp(human, id)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    local curPetConfig = Config[PetConfig[id].petName]
    local nextStarInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAR, data.star + 1)
    if not nextStarInfo then
        return
    end

    if ObjHuman.getYinliang(human) < nextStarInfo.needYinliang then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_STAR_UP_YINLIANG_NOT_ENOUGH)
    end
    if BagLogic.getItemCount(human, PetConfig[id].needItem) < nextStarInfo.upStarItemCnt then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_STAR_UP_ITEM_NOT_ENOUGH)
    end
    ObjHuman.decYinliang(human, nextStarInfo.needYinliang, "pet")
    BagLogic.delItemsById(human, PetConfig[id].needItem, nextStarInfo.upStarItemCnt, "pet")
    data.star = data.star + 1
    updatePet(human, id)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_STAR_UP_OK)
    ObjHuman.doCalc(human)
    addAllRA(human)
    if human.db.petCombatId == id then
        ObjPet.update(human)
    end
    local str = string.format(Lang.PET_STAR_BROCAST, HtmlUtil.fontName(human.name, human._id), PetConfig[id].petMingzi, data.star, human._id)
    Broadcast.sendBroadcast2World(Lang.UP+Lang.GROSSIP, str)
    Log.write(Log.LOGID_OSS_PET_STAR,human._id,human.account,human.name,human.db.lv,id, data.star-1, data.star)
end
--升阶
function stageUp(human, id)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    for i=0, 3 do
        if data.equipStatus[i] ~= 1 then
            return
        end
    end
    local curPetConfig = Config[PetConfig[id].petName]
    local nextStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage + 1)
    if not nextStageInfo then
        return
    end
    if ObjHuman.getYinliang(human) < nextStageInfo.needYinliang then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_STAGE_UP_YINLIANG_NOT_ENOUGH)
    end
    ObjHuman.decYinliang(human, nextStageInfo.needYinliang, "pet")
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage)
    if curStageInfo.haveSkillCount ~= nextStageInfo.haveSkillCount then
        for i=1, nextStageInfo.haveSkillCount do
            if i > curStageInfo.haveSkillCount then
                data.skillLv[i - 1] = 1
            end
        end
    end
    for i=0, 3 do
        data.equipStatus[i] = 0
    end
    data.stage = data.stage + 1
    updatePet(human, id)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_STAGE_UP_OK)
    ObjHuman.doCalc(human)
    addAllRA(human)
    if human.db.petCombatId == id then
        ObjPet.update(human)
    end
    local str = string.format(Lang.PET_STAGE_BROCAST, HtmlUtil.fontName(human.name, human._id), PetConfig[id].petMingzi, ItemDefine.getText(data.stage), human._id)
    Broadcast.sendBroadcast2World(Lang.UP+Lang.GROSSIP, str)
    Log.write(Log.LOGID_OSS_PET_STAGE,human._id,human.account,human.name,human.db.lv,id, data.stage-1, data.stage, getSkillCnt(id,data.stage))
end
--激活
function jihuo(human, id)
    local data = ObjHuman.getPet(human, id)
    if data and data.startTime == 0 then
        return
    end
    if BagLogic.getItemCount(human, PetConfig[id].needItem) < PetConfig[id].jihuoNeedCnt then
      return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_JIHUO_ITEM_NOT_ENOUGH)
    end
    BagLogic.delItemsById(human, PetConfig[id].needItem, PetConfig[id].jihuoNeedCnt, "pet")
    local curPetConfig = Config[PetConfig[id].petName]
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 1)
    if data then
      data.startTime = 0
      data.limitTime = 0
      data.status = 1 
    else
      if id == 1 then
        data = ObjHuman.addPet(human, id, PetConfig[id].baseStar, curStageInfo.haveSkillCount, 25)
      else
        curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 2)        
        data = ObjHuman.addPet(human, id, PetConfig[id].baseStar, curStageInfo.haveSkillCount, 25, 2)
      end  
      for i=1, curStageInfo.haveSkillCount do
          if data.skillLv[i - 1] == 0 then
              data.skillLv[i - 1] = 1
          end
      end
    end
    Log.write(Log.LOGID_OSS_PET_JIHUO, human._id,human.account,human.name,human.db.lv,id,getSkillCnt(id, 1))
    updatePet(human, id)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_JIHUO_OK)
    ObjHuman.doCalc(human)
    addAllRA(human)
end
--判断这个培养值是否已满,true已经满了
function checkFeedFull(human, index, data, config)
    if index <= 4 then
        if data.feedAttrVal[index - 1] >= config.maxAddPetAttr[index][2] then
            return true
        end
    else
        if data.feedAttrVal[index - 1] >= config.maxAddRoleAttr[index - 4][2] then
            return true
        end
    end
    return false
end
--判断所有培养值是否已满
function checkAllFeedFull(human, data, config)
    local cnt = 0
    for i=1, 8 do
        if not checkFeedFull(human, i, data, config) then
            cnt = cnt + 1
        end
    end
    return cnt
end
--计算培养值
function calcFeedValue(human, index, data, config)
    if index <= 4 then
        return math.random(config.feedPetAttr[index][2], config.feedPetAttr[index][3])
    else
        return math.random(config.feedRoleAttr[index - 4][2], config.feedRoleAttr[index - 4][3])
    end
end
--判断是否已拥有培养值
function checkHaveFeed(human, index)
    for i=1, #human.petFeed do
        if human.petFeed[i].index == index then
            return true
        end
    end
    return false
end
--计算培养属性
function randFeed(human, id, data, len)
    human.petFeed = human.petFeed or {}
    local feedConfig= Config.feedAttrCnt
    local curPetConfig = Config[PetConfig[id].petName][1]
    local notFeedFullCnt = checkAllFeedFull(human, data, curPetConfig)
    if notFeedFullCnt == 0 then
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_FEED_HAVE_FULL)
        return false
    end
    local progress = 0
    for i=0, 3 do
        progress = data.feedAttrVal[i]/curPetConfig.maxAddPetAttr[i+1][2]
    end
    for i=4, 7 do
        progress = data.feedAttrVal[i]/curPetConfig.maxAddRoleAttr[i-3][2]
    end
    progress = math.floor(progress/len * 20)
    local feedWeight = {} --喂养权重
    for i = #feedConfig, 1, -1 do
        if progress < feedConfig[i].progress then
            feedWeight = feedConfig[i].weight
            break
        end
    end
    if progress == 0 then
        feedWeight = feedConfig[1].weight
    end
    local totalWeight = 0
    for i=1, notFeedFullCnt do
        totalWeight = totalWeight + feedWeight[i]
    end
    local randNum = math.random(1, totalWeight)
    local cnt = 0
    totalWeight = 0
    for i=1, notFeedFullCnt do
        totalWeight = totalWeight + feedWeight[i]
        if randNum <= totalWeight then
            cnt = i
            break
        end
    end
    local start = math.random(1,  len)
    local index = 1
    local curCnt = 0
    for i=1, 8 do--  while cnt > 0 do
        if not checkHaveFeed(human, start) and not checkFeedFull(human, start, data, curPetConfig) and math.random(1,2) == 2 then
            human.petFeed[index] = {}
            human.petFeed[index].index = start
            human.petFeed[index].value = calcFeedValue(human, start, data, curPetConfig)
            index = index + 1
            curCnt = curCnt + 1
        end
        start = start + 1
        if start > len then
            start = 1
        end
        if cnt == curCnt then
            break
        end
    end
    if curCnt < cnt then
        for i=1, 8 do--  while cnt > 0 do
            if not checkHaveFeed(human, start) and not checkFeedFull(human, start, data, curPetConfig) then
                human.petFeed[index] = {}
                human.petFeed[index].index = start
                human.petFeed[index].value = calcFeedValue(human, start, data, curPetConfig)
                index = index + 1
                curCnt = curCnt + 1
            end
            start = start + 1
            if start > len then
                start = 1
            end
            if cnt == curCnt then
                break
            end
        end
    end
    return true
end
--将培养值加到数据库
function addFeedAttr(human, data, config)
    for i=1,#human.petFeed do
        data.feedAttrVal[human.petFeed[i].index - 1] = data.feedAttrVal[human.petFeed[i].index - 1] + human.petFeed[i].value
        if human.petFeed[i].index <= 4 and data.feedAttrVal[human.petFeed[i].index - 1] > config.maxAddPetAttr[human.petFeed[i].index][2] then
            data.feedAttrVal[human.petFeed[i].index - 1] = config.maxAddPetAttr[human.petFeed[i].index][2]
        elseif human.petFeed[i].index > 4 and data.feedAttrVal[human.petFeed[i].index - 1] > config.maxAddRoleAttr[human.petFeed[i].index - 4][2] then
            data.feedAttrVal[human.petFeed[i].index - 1] = config.maxAddRoleAttr[human.petFeed[i].index - 4][2]
        end
    end
end
--培养
function petFeed(human, id, type)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    if data.star < 5 or type > 99 then
        return
    end
    local curPetConfig = Config[PetConfig[id].petName][1]
    if checkAllFeedFull(human, data, curPetConfig) == 0 then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_FEED_HAVE_FULL)
    end
    if ObjHuman.getYinliang(human) < 10000 * ((type == 0) and 1 or type) then
      return Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.YINLIANG_NOT_ENOUGH)
    end
    local cnt = BagLogic.getItemCount(human, PetConfig[id].needItem)
    if cnt < 1 or cnt < type then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_FEED_ITEM_NOT_ENOUGH)
    end
    if type == 0 then
        if randFeed(human, id, data, 8) then
            addFeedAttr(human, data, curPetConfig)
            human.petFeed = nil
            BagLogic.delItemsById(human, PetConfig[id].needItem, 1, "pet")
            ObjHuman.decYinliang(human, 10000,"pet")
        end
    else
        local useCnt = 0
        for i=1, type do
            if randFeed(human, id, data, 8) then
                useCnt = useCnt + 1
                addFeedAttr(human, data, curPetConfig)
                human.petFeed = nil
            end
        end
        BagLogic.delItemsById(human, PetConfig[id].needItem, useCnt, "pet")
        ObjHuman.decYinliang(human, 10000 * useCnt,"pet")
    end
    updatePet(human, id)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_FEED_OK)
    ObjHuman.doCalc(human)
    addAllRA(human)
end
--设置神将状态
function setStatus(human, data)
    if data.status == 2 then
        data.status = 1
        if data.id == human.db.petCombatId then
            human.db.petCombatId = 0
            ObjPet.daiji(human)
        end
    elseif data.status == 1 then
        data.status = 2
        human.db.petCombatId = data.id
        HandlerL.CG_PET_COMBAT(human, data.id)
    end
end
--神将状态改变
function statusChange(human, id)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return false
    end
    if ObjHuman.checkIsInFighting(human) then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_IS_COMBATING)
    end
    if ExcelMap.scene[Map.scene_id_to_map_id[human.scene_id]].can_use_pet == 0 and human.db.petCombatId ~= id then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_CANNNOT_COMBAT)
    end
    local tmpId = human.db.petCombatId
    local comBatData = ObjHuman.getPet(human, tmpId)
    if comBatData and comBatData.hp < 1 then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_HAVE_DIE)
    end
    if tmpId ~= 0 and id ~= tmpId then
        if comBatData.status == 2 then
            setStatus(human, comBatData)
            updatePet(human, tmpId)
        end
    end
    setStatus(human, data)
    updatePet(human, id)
    addAllRA(human)
    ObjHuman.doCalc(human)
end
--神将装备合成
function equipHecheng(human, id, equipIndex)
    local data = ObjHuman.getPet(human, id)
    if not data or data.equipStatus[equipIndex] == 1 then
        return
    end
    local hechengConfig = Config.equipHecheng
    local curPetConfig = Config[PetConfig[id].petName]
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage)
    for i=1, #hechengConfig do
        if hechengConfig[i].id == curStageInfo.needEquip[equipIndex + 1] then
            if ObjHuman.getYinliang(human) < hechengConfig[i].needYL then
                return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_HECHENG_YINLIANG_NOT_ENOUGH)
            end
            for j=1, #hechengConfig[i].needItem do
                if BagLogic.getItemCount(human, hechengConfig[i].needItem[j][1]) < hechengConfig[i].needItem[j][2] then
                    return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_HECHENG_ITEM_NOT_ENOUGH)
                end
            end
            if data.lv < hechengConfig[i].needLv then
                return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_HECHENG_LV_NOT_ENOUGH)
            end

            for j=1, #hechengConfig[i].needItem do
                BagLogic.delItemsById(human, hechengConfig[i].needItem[j][1], hechengConfig[i].needItem[j][2], "pet")
            end
            ObjHuman.decYinliang(human, hechengConfig[i].needYL, "pet")
            data.equipStatus[equipIndex] = 1
            updatePet(human, id)
            Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_EQUIP_HECHENG_OK)
            ObjHuman.doCalc(human)
            addAllRA(human)
            return
        end
    end
end
--查看合成神将装备所需材料
function checkEquip(human, id)--, equipIndex)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    local sendMsg = Msg.gc.GC_CHECK_PET_EQUIP
    local hechengConfig = Config.equipHecheng
    local curPetConfig = Config[PetConfig[id].petName]
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, data.stage)
    local cache = {}
    sendMsg.info[0] = #curStageInfo.needEquip
    for kk=1, #curStageInfo.needEquip do
        for i=1, #hechengConfig do
            if hechengConfig[i].id == curStageInfo.needEquip[kk] then
                sendMsg.info[kk].needItem[0] = #hechengConfig[i].needItem
                for j=1, #hechengConfig[i].needItem do
                    Grid.create(cache, hechengConfig[i].needItem[j][1], hechengConfig[i].needItem[j][2])
                    Grid.makeItem(cache, sendMsg.info[kk].needItem[j], 0, human)
                end
                sendMsg.info[kk].needYL = hechengConfig[i].needYL
                sendMsg.info[kk].needLv = hechengConfig[i].needLv
                break
            end
        end
    end
    sendMsg.id = id
    Msg.send(sendMsg, human.fd)
end
--额外技能等级战斗力
function getSkillZhandouli(human, id)
    local data = ObjHuman.getPet(human, id)
    if data == nil then
        return 0
    end
    local config = PetConfig[id]
    local value = 0
    local len = #config.skillId
    if len > 4 then
        len =4
    end
    for i = 1, len do
        value = value + data.skillLv[i-1]
    end
    return value
end
--计算所有神将对人物属性的加成
function addAllRA(human, noSend, isReturn)
    local sendMsg = Msg.gc.GC_ALL_PET_ADD_ROLE_ATTR
    sendMsg.addAttr[0] = 0
    for i = 0, human.db.petLen -1 do
      if human.db.pet[i].status ~= 0 then
        calcRA(human, human.db.pet[i].id, sendMsg.addAttr, nil, i)
      end
    end
    sendMsg.curAtticAddAttr[0] = sendMsg.addAttr[0]
    for i=1, sendMsg.curAtticAddAttr[0] do
        sendMsg.curAtticAddAttr[i].key = sendMsg.addAttr[i].key
        sendMsg.curAtticAddAttr[i].value = sendMsg.addAttr[i].value * (human.db.petAtticLv > 0 and (AtticConfig[human.db.petAtticLv].addPer/100 + 1) or 1)
    end
    sendMsg.power = RoleAttr.calPowerProto(sendMsg.curAtticAddAttr) + skillZhandouli(human)
    YYDaBiao.checkCanGet(human, AcvityDefine.OPERATEACT_TYPE_PET, sendMsg.power)
    if not noSend then
        if not isReturn then
            Msg.send(sendMsg, human.fd)
            if sendMsg.power ~= 0 then
                local powerMsg = Msg.lw.LW_CHECK_RANK_CHANGE
                powerMsg.type = RankDefine.PET_RANK_TYPE
                powerMsg.otherInfo = sendMsg.power
                Msg.send2world(powerMsg, human._id)
            end
            sendAtticInfo(human)
        end
        return sendMsg.power
    else
        for i=1, sendMsg.curAtticAddAttr[0] do
            human.attr[sendMsg.curAtticAddAttr[i].key] = human.attr[sendMsg.curAtticAddAttr[i].key] + sendMsg.curAtticAddAttr[i].value
        end
    end
end
--激活限时神将
function jihuoLimitPet(human, id, limitTime, itemId, itemCnt)
    local data = ObjHuman.getPet(human, id)
    local curPetConfig = Config[PetConfig[id].petName]
    local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 1)
    if not data then
      if id == 1 then
        data = ObjHuman.addPet(human, id, PetConfig[id].baseStar, curStageInfo.haveSkillCount, 25)
      else
        curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 2)
        data = ObjHuman.addPet(human, id, PetConfig[id].baseStar, curStageInfo.haveSkillCount, 25, 2)
      end  
      for i=1, curStageInfo.haveSkillCount do
        if data.skillLv[i - 1] == 0 then
          data.skillLv[i - 1] = 1
        end
      end
    else
      if data.startTime == 0 then --已经永久激活
        if not BagLogic.checkCanAddItem(human, itemId, true, itemCnt) then
          return Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.BAG_FULL)
        else
          BagLogic.addItem(human, itemId, true, itemCnt, "pet")
          return true
        end
      end
      data.status = 1
    end
    data.startTime = os.time()
    data.limitTime = limitTime    
    updatePet(human, id)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_JIHUO_OK)
    ObjHuman.doCalc(human)
    addAllRA(human)
    return true
end
--检查神将是否到期
function checkLimtPet(human)
    for i = 0, human.db.petLen -1 do
      local data = human.db.pet[i]
      if data.startTime ~= 0 and data.limitTime ~= 0 and data.limitTime <= (os.time() - data.startTime + 10) then
        human.db.pet[i].limitTime = 0          
        human.db.pet[i].status = 0
        if data.id == human.db.petCombatId then
          human.db.petCombatId = 0
          ObjPet.daiji(human)
        end
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.PET_LIMIT_EXPIRE)
        ObjHuman.doCalc(human)
        addAllRA(human)
        updatePet(human, data.id)
      end
    end
end

function initAttr(human, pet)
    local attrs = {}
    for i=1, 8 do
        attrs[i] = {}
    end
    calcPA(human, pet.db.id, attrs)
    for i=1, attrs[0] do
        pet.attr[attrs[i].key] = attrs[i].value
    end
end

function getCanUseSkill(uuid, id, tb)
    local human = ObjHuman.onlineUuid[uuid]
    if human then
        getCanUseSkillHuman(human, id, tb)
    end
end
function getCanUseSkillHuman(human, id, tb)
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    for i = 1, #PetConfig[id].skillId do
        if data.skillLv[i-1] ~= 0 then
            tb[i] = {}
            tb[i].skillId = PetConfig[id].skillId[i]
            tb[i].skillLv = data.skillLv[i-1]
        else
            break
        end
    end
end

--发送神将阁信息
function sendAtticInfo(human)
    local sendMsg = Msg.gc.GC_PET_ATTIC_INFO
    sendMsg.curLv = human.db.petAtticLv
    sendMsg.curPro = human.db.petAtticPro
    sendMsg.nextAddAttr[0] = 0
    for i = 0, human.db.petLen -1 do
        calcRA(human, human.db.pet[i].id, sendMsg.nextAddAttr, nil, i)
    end
    if human.db.petAtticLv > 0 then
        sendMsg.curAddAttr[0] = sendMsg.nextAddAttr[0]
        for i=1, sendMsg.curAddAttr[0] do
            sendMsg.curAddAttr[i].key = sendMsg.nextAddAttr[i].key
            sendMsg.curAddAttr[i].value = sendMsg.nextAddAttr[i].value * (AtticConfig[human.db.petAtticLv].addPer/100 + 1)
        end
        sendMsg.curAddPer = AtticConfig[human.db.petAtticLv].addPer
    else
        sendMsg.curAddAttr[0] = 0
        sendMsg.curAddPer = 0
    end
    if human.db.petAtticLv < #AtticConfig then
        sendMsg.nextAddPer = AtticConfig[human.db.petAtticLv + 1].addPer
        for i=1, sendMsg.nextAddAttr[0] do
            sendMsg.nextAddAttr[i].value = sendMsg.nextAddAttr[i].value * (AtticConfig[human.db.petAtticLv + 1].addPer/100 + 1)
        end
        sendMsg.nextPower = RoleAttr.calPowerProto(sendMsg.nextAddAttr) + skillZhandouli(human)
        local cache = {}
        sendMsg.nextNeedItem[0] = 1
        Grid.create(cache, AtticConfig[human.db.petAtticLv + 1].needItem[1], AtticConfig[human.db.petAtticLv + 1].needItem[2])
        Grid.makeItem(cache, sendMsg.nextNeedItem[1], 0, human)
        sendMsg.totalPro = AtticConfig[human.db.petAtticLv + 1].totalPro
    else
        sendMsg.nextAddAttr[0] = 0
        sendMsg.nextAddPer = 0
        sendMsg.nextPower = 0
        sendMsg.nextNeedItem[0] = 0
        sendMsg.totalPro = 0
    end
    Msg.send(sendMsg, human.fd)
end
--计算神将阁升级进度
function upgradeAttic(human)
    local tmpConfig = AtticConfig[human.db.petAtticLv + 1]
    local addExp = tmpConfig.addExp
    local randNum = math.random(1, 10000)
    local totalWight = 0
    for i=1, #tmpConfig.weight do
        totalWight = tmpConfig.weight[i][2]
        if randNum <= totalWight then
            addExp = addExp * tmpConfig.weight[i][1]
        end
    end
    if addExp + human.db.petAtticPro >= tmpConfig.totalPro then
        human.db.petAtticLv = human.db.petAtticLv + 1
        human.db.petAtticPro = addExp + human.db.petAtticPro - tmpConfig.totalPro
        addAllRA(human)
        ObjHuman.doCalc(human)
    else
        human.db.petAtticPro = human.db.petAtticPro + addExp
    end
end
--神将阁升级
function atticLvUp(human)
    if human.db.petAtticLv >= #AtticConfig then
        return
    end
    if BagLogic.getItemCount(human, AtticConfig[human.db.petAtticLv + 1].needItem[1]) < AtticConfig[human.db.petAtticLv + 1].needItem[2] then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_ATTIC_ITEM_NOT_ENOUGH)
    end
    BagLogic.delItemsById(human, AtticConfig[human.db.petAtticLv + 1].needItem[1], AtticConfig[human.db.petAtticLv + 1].needItem[2], "pet")
    upgradeAttic(human)
    sendAtticInfo(human)
end
--发送神将升级可用道具信息
function sendPetLvItem(human)
    local sendMsg = Msg.gc.GC_PET_LV_UP_ITEM_INFO
    local cache = {}
    sendMsg.item[0] = #OtherConfig
    for i=1, #OtherConfig do
        Grid.create(cache, OtherConfig[i].itemId, 1)
        Grid.makeItem(cache, sendMsg.item[i], 0, human)
    end
    Msg.send(sendMsg, human.fd)
end
--神将加经验
function addExp(human, exp)
    if human.db.petCombatId == 0 then
        return
    end
    local exp = math.floor(exp * PetDefine.PEY_EXP_PERCENT)
    local data = ObjHuman.getPet(human, human.db.petCombatId)
    local petLvConfig = Config[PetConfig[human.db.petCombatId].petName .. "Lv"]
    if data.lv > human.db.lv or (data.lv == human.db.lv and data.exp == petLvConfig[data.lv].needExp) then
        return
    end
    data.exp = data.exp + exp
    while data.exp > petLvConfig[data.lv].needExp do
        if data.lv + 1 > human.db.lv then
            data.exp = petLvConfig[data.lv].needExp
        else
            data.exp = data.exp - petLvConfig[data.lv].needExp
            data.lv = data.lv + 1
            ObjPet.update(human)
            addAllRA(human)
            ObjHuman.doCalc(human)
            updatePet(human, human.db.petCombatId)
            Log.write(Log.LOGID_OSS_PET_LV,human._id,human.account,human.name,human.db.lv,data.id,data.lv, 1)
        end
    end
    updateExp(human, human.db.petCombatId)
    OfficialLogic.checkOneCondition(human, "petLv")
end
function checkCanUp(itemId)
    for i=1, #OtherConfig do
        if OtherConfig[i].itemId == itemId then
            return OtherConfig[i]
        end
    end
end
--神将用道具加经验
function addExpItem(human, id, itemId, cnt, isUse, useIndex)
    if isUse and human.db.petCombatId == 0 then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_NOT_HAVE_COMBAT_ID)
    end
    if isUse then
        id = human.db.petCombatId
    end
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
    if data.lv > human.db.lv or (data.lv == human.db.lv and data.exp == petLvConfig[data.lv].needExp) then
        return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_LV_UP_ERR_CANNOT_UP)
    end
    local tmpConfig = checkCanUp(itemId)
    if not tmpConfig then
        return
    end
    if BagLogic.getItemCount(human, itemId) < cnt then
        return
    end
    local beforeLv = data.lv
    local totalExp = 0
    local useCnt = 0
    for i=1, cnt do
        if data.lv > human.db.lv or (data.lv == human.db.lv and data.exp == petLvConfig[data.lv].needExp) then
            Broadcast.sendBroadcast(human, Lang.DOWN, Lang.PET_LV_UP_ERR_CANNOT_UP)
            break
        end
        local exp = tmpConfig.addUpVal
        data.exp = data.exp + exp
        totalExp = totalExp + exp
        while data.exp > petLvConfig[data.lv].needExp do
            if data.lv + 1 > human.db.lv then
                data.exp = petLvConfig[data.lv].needExp
                break
            else
                data.exp = data.exp - petLvConfig[data.lv].needExp
                data.lv = data.lv + 1
                if human.db.petCombatId == id then
                    ObjPet.update(human)
                end
                addAllRA(human)
                ObjHuman.doCalc(human)
                Log.write(Log.LOGID_OSS_PET_LV,human._id,human.account,human.name,human.db.lv,data.id,data.lv, 2)
            end
        end
        useCnt = useCnt + 1
    end
    BagLogic.delItemsById(human, itemId, useCnt, "pet")
  
    Broadcast.sendBroadcast(human, Lang.DOWN, string.format(Lang.PET_LV_UP_SUCCESS, totalExp))
    if beforeLv ~= data.lv then
        updatePet(human, id)
    else
        updateExp(human, id)
    end
    OfficialLogic.checkOneCondition(human, "petLv")
end

function setPetShowInfo(info, id)
    for i=1, #PetConfig do
        if i == id then
            info.id = PetConfig[i].source
            info.effect = 0
            info.attr[0] = 0
            info.type = 2
            local curPetConfig = Config[PetConfig[id].petName]
            local curStageInfo = getCurLvPetInfo(curPetConfig, PetDefine.PET_STAGE, 2)
            RoleAttr.addAttrs(info.attr, curStageInfo.addRoleAttr)
            local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
            RoleAttr.addAttrs(info.attr, petLvConfig[25].addAttr)
            info.power = RoleAttr.calPowerProto(info.attr)
        end
    end
end

function updateExp(human, id)
    local sendMsg = Msg.gc.GC_UPDATE_PET_EXP
    local data = ObjHuman.getPet(human, id)
    if not data then
        return
    end
    local petLvConfig = Config[PetConfig[id].petName .. "Lv"]
    sendMsg.id = id
    sendMsg.exp = data.exp
    sendMsg.totalExp = petLvConfig[data.lv].needExp
    Msg.send(sendMsg, human.fd)
end

SKILL_ZHANDOULI = {5,10,15,20}
function skillZhandouli(human)
    local data = ObjHuman.getPet(human, human.db.petCombatId)
    if data == nil then
        return 0
    end
    local ret = 0
    for i = 1, 4 do
        ret  = ret + SKILL_ZHANDOULI[i] * data.skillLv[i-1]
    end
    return ret
end

function onSkillUpGrade(human, index, id)
    for i = 0, human.db.petLen-1 do
        local data = human.db.pet[i]
        local config = PetConfig[data.id]
        for k,v in pairs(config.skillId) do
            if v == id then
                addAllRA(human)
                updatePet(human, data.id)
                break
            end
        end
    end
end

function getPetLvCount(human, lv)
  local count = 0
  for i=1, #PetConfig do
    local data = ObjHuman.getPet(human, i)
    if data and data.lv >= lv then
      count = count + 1
    end
  end
  return count
end

